package service.impl;

import com.google.common.collect.ImmutableList;
import common.consts.Consts;
import common.consts.Offers;
import dao.*;
import domain.Account;
import domain.Offer;
import domain.PushMessage;
import domain.Recruitment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import service.RejectService;
import service.ServiceResponse;
import service.util.MessagePushUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by aceyin on 15/7/2.
 */


@Service
public class RejectServiceImpl extends ServiceBase implements RejectService {
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private RecruitmentDao recruitmentDao;
    @Autowired
    private OfferDao offerDao;
    @Autowired
    private PushMessageDao pushMessageDao;
    @Autowired
    private UserDataProfileDao userDataProfileDao;

    @Override
    @Transactional
    public ServiceResponse reject(long employer, long applier, long recruitmentId) {
        Account account = accountDao.get(applier);
        if (account == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_USER);
        }
        Recruitment recruitment = recruitmentDao.get(recruitmentId);
        if (recruitment == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_RECRUITMENT);
        }

        long owner = recruitment.getOwner();
        if (owner != employer) {
            return ServiceResponse.fail(Consts.i18nKey.INVALID_REQUEST);
        }

        Offer offer = offerDao.findOffer(recruitmentId, applier);
        if (offer == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_OFFER);
        }

        String status = offer.getStatus();
        if (status == null) {
            return ServiceResponse.fail(Consts.i18nKey.INVALID_OFFER_STATUS);
        }

        //已经是cancel状态的不需要再次被cancel，否则其他状态的都可以被cancel，即便是 EMPLOYED 状态
        if (Offers.isCanceled(status)) {
            return ServiceResponse.success();
        } else {
            Long id = offer.getId();
            List<Long> ids = ImmutableList.<Long>builder().add(id).build();
            offerDao.updateOfferStatus(Offers.Status.CANCELED.name(), ids);
            // 更新 recruitment 的已录用人数
            Integer recruitQuantity = recruitment.getRecruitQuantity();
            recruitQuantity = recruitQuantity == null ? 0 : recruitQuantity;
            int recruited = recruitQuantity - 1;
            recruited = recruited < 0 ? 0 : recruited;
            recruitmentDao.updateRecruitQuantity(recruitmentId, recruited);
            // 发送消息
            Account employerAccount = accountDao.get(owner);
            PushMessage message = MessagePushUtil.createRejectMessage(applier, employerAccount.getNick());
            pushMessageDao.insert(message);

            long applierId = offer.getApplier();
            List<Long> list = ImmutableList.<Long>builder().add(applierId).build();
            userDataProfileDao.decreaseEmployQuantity(list);
        }

        return ServiceResponse.success();
    }

    @Override
    @Transactional(readOnly = false)
    public ServiceResponse rejectAll(long employerId, long recruitmentId) {
        Recruitment recruitment = recruitmentDao.get(recruitmentId);
        if (recruitment == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_RECRUITMENT);
        }
        Account employer = accountDao.get(employerId);
        if (employer == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_EMPLOYER);
        }

        long owner = recruitment.getOwner();
        if (owner != employerId) {
            return ServiceResponse.fail(Consts.i18nKey.INVALID_REQUEST);
        }

        List<Offer> offers = offerDao.getAllOffersByStatus(recruitmentId, employerId, Offers.Status.WAITING.name());
        if (offers == null || offers.isEmpty()) {
            return ServiceResponse.fail(Consts.i18nKey.NO_OFFER_CAN_BE_REJECTED);
        }


        String nick = employer.getNick();
        List<Long> offerIds = new ArrayList<>();
        List<Long> applierIds = new ArrayList<>();
        Integer recruitQuantity = recruitment.getRecruitQuantity();
        int recruited = recruitQuantity == null ? 0 : recruitQuantity.intValue();

        List<PushMessage> messages = new ArrayList<>();
        for (Offer offer : offers) {
            offerIds.add(offer.getId());
            applierIds.add(offer.getApplier());
            PushMessage message = MessagePushUtil.createRejectMessage(offer.getApplier(), nick);
            messages.add(message);
            recruited--;
        }
        recruited = recruited <= 0 ? 0 : recruited;
        recruitmentDao.updateRecruitQuantity(recruitmentId, recruited);
        offerDao.updateOfferStatus(Offers.Status.CANCELED.name(), offerIds);
        pushMessageDao.batchInsert(messages);
        userDataProfileDao.decreaseEmployQuantity(applierIds);

        return ServiceResponse.success();
    }

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void setRecruitmentDao(RecruitmentDao recruitmentDao) {
        this.recruitmentDao = recruitmentDao;
    }

    public void setOfferDao(OfferDao offerDao) {
        this.offerDao = offerDao;
    }

    public void setPushMessageDao(PushMessageDao pushMessageDao) {
        this.pushMessageDao = pushMessageDao;
    }
}
